package aidturith.db.beans;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

@Entity
@Table(name = "music_table")
public class Music {

	@Id
	@GeneratedValue
	@Column(name = "music_id")
	private int music_id;

	@Column(name = "music_title", nullable = false, updatable = true, unique = false)
	private String music_title;

	@Column(name = "music_track", nullable = true, updatable = true, unique = false)
	private int music_track;

	@Column(name = "music_rating", nullable = true, updatable = true, unique = false)
	private int music_rating;

	@Column(name = "music_listen_time", nullable = false, updatable = true, unique = false)
	private long music_listen_time;

	@Column(name = "music_listen_count", nullable = false, updatable = true, unique = false)
	private int music_listen_count;

	@OneToOne(cascade=javax.persistence.CascadeType.ALL)
	@JoinColumn(name="file_id")
	private File file;

	@ManyToOne
	@JoinColumn(name = "id_album")
	private Album album;

	@ManyToMany(cascade = {javax.persistence.CascadeType.ALL})
	@JoinTable(name="music_genre_table",
	joinColumns={@JoinColumn(name="music_id")},
	inverseJoinColumns={@JoinColumn(name="genre_id")})
	private Set<Genre> genres = new HashSet<Genre>();

	@ManyToMany(cascade = {javax.persistence.CascadeType.ALL})
	@JoinTable(name="music_subtitle_table",
	joinColumns={@JoinColumn(name="music_id")},
	inverseJoinColumns={@JoinColumn(name="subtitle_id")})
	private Set<Subtitle> subtitles = new HashSet<Subtitle>();

	@ManyToMany(cascade = {javax.persistence.CascadeType.ALL})
	@JoinTable(name="composer_table",
	joinColumns={@JoinColumn(name="music_id")},
	inverseJoinColumns={@JoinColumn(name="artist_id")})
	private Set<Artist> composers = new HashSet<Artist>();

	@ManyToMany(cascade = {javax.persistence.CascadeType.ALL})
	@JoinTable(name="arranger_table",
	joinColumns={@JoinColumn(name="music_id")},
	inverseJoinColumns={@JoinColumn(name="artist_id")})
	private Set<Artist> arrangers = new HashSet<Artist>();

	@ManyToMany(cascade = {javax.persistence.CascadeType.ALL})
	@JoinTable(name="lyricist_table",
	joinColumns={@JoinColumn(name="music_id")},
	inverseJoinColumns={@JoinColumn(name="artist_id")})
	private Set<Artist> lyricists = new HashSet<Artist>();

	@ManyToMany(cascade = {javax.persistence.CascadeType.ALL})
	@JoinTable(name="vocalist_table",
	joinColumns={@JoinColumn(name="music_id")},
	inverseJoinColumns={@JoinColumn(name="artist_id")})
	private Set<Artist> vocalists = new HashSet<Artist>();

	@OneToMany(mappedBy="music")
	@Cascade({CascadeType.ALL})
	private Set<Alias> aliases = new HashSet<Alias>();

	@ManyToMany(mappedBy="musics")
	private Set<Playlist> playlists = new HashSet<Playlist>();

	public Music() {
		super();
	}

	public Music(String music_title) {
		super();
		this.music_title = music_title;
		music_listen_time = 0;
		music_listen_count = 0;
	}

	public Music(String music_title, int music_track) {
		super();
		this.music_title = music_title;
		this.music_track = music_track;
		music_listen_time = 0;
		music_listen_count = 0;
	}

	public String getMusic_title() { return music_title; }
	public void setMusic_title(String music_title) { this.music_title = music_title; }

	public int getMusic_track() { return music_track; }
	public void setMusic_track(int music_track) { this.music_track = music_track; }

	public int getMusic_rating() { return music_rating; }
	public void setMusic_rating(int music_rating) { this.music_rating = music_rating; }

	public long getMusic_listen_time() { return music_listen_time; }
	public void setMusic_listen_time(long music_listen_time) { this.music_listen_time = music_listen_time; }

	public int getMusic_listen_count() { return music_listen_count; }
	public void setMusic_listen_count(int music_listen_count) { this.music_listen_count = music_listen_count; }

	public File getFile() { return file; }
	public void setFile(File file) { this.file = file; }

	public Album getAlbum() { return album; }
	public void setAlbum(Album album) { this.album = album; }

	public Set<Genre> getGenres() { return genres; }
	public void setGenres(Set<Genre> genres) { this.genres = genres; }

	public void addGenre(Genre genre) {
		getGenres().add(genre);
		genre.getMusics().add(this);
	}

	public Set<Subtitle> getSubtitles() { return subtitles; }
	public void setSubtitles(Set<Subtitle> subtitles) { this.subtitles = subtitles; }

	public void addSubtitle(Subtitle subtitle) {
		getSubtitles().add(subtitle);
		subtitle.getMusics().add(this);
	}

	public Set<Artist> getComposers() { return composers; }
	public void setComposers(Set<Artist> composers) { this.composers = composers; }

	public void addComposer(Artist artist) {
		getComposers().add(artist);
		artist.getMusic_compossed().add(this);
	}

	public Set<Artist> getArrangers() { return arrangers; }
	public void setArrangers(Set<Artist> arrangers) { this.arrangers = arrangers; }

	public void addArranger(Artist artist) {
		getArrangers().add(artist);
		artist.getMusic_arranged().add(this);
	}

	public Set<Artist> getLyricists() { return lyricists; }
	public void setLyricists(Set<Artist> lyricists) { this.lyricists = lyricists; }

	public void addLyrist(Artist artist) {
		getLyricists().add(artist);
		artist.getMusic_written().add(this);
	}

	public Set<Artist> getVocalists() { return vocalists; }
	public void setVocalists(Set<Artist> vocalists) { this.vocalists = vocalists; }

	public void addVocalist(Artist artist) {
		getVocalists().add(artist);
		artist.getMusic_sung().add(this);
	}

	public Set<Alias> getAliases() { return aliases; }
	public void setAliases(Set<Alias> aliases) { this.aliases = aliases; }

	public Set<Playlist> getPlaylists() { return playlists; }
	public void setPlaylists(Set<Playlist> playlists) { this.playlists = playlists; }

	@Override
	public String toString() { return music_title; }

}
